package com.chijun.mform;

import android.content.Context;
import android.util.Pair;
import android.view.View;

import com.chijun.mform.create.mode.FormFieldOption;
import com.chijun.mform.create.mode.FormOptionReField;
import com.example.ccj.b.c.custom.image.MLocalMedia;
import com.example.ccj.u.server.MyObserver;
import com.example.ccj.u.tengxun.cos.COS;
import com.example.ccj.u.tengxun.cos.CosDeleteCallBack;
import com.example.ccj.u.tengxun.cos.CosUploadCallBack;
import com.example.ccj.u.tengxun.cos.CosUploadMultipleCallBack;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;


public class FormUtils {

    /**
     * 上传单张图片到COS
     * @param context 上下文
     * @param localMedia 图片
     * @param uploadCallBack 上传完毕回调
     */
    public static void cosUploadMedia(Context context, MLocalMedia localMedia, UploadMediaListener uploadCallBack){
        cosUpload(context, localMedia.urlPath, localMedia.getRealPath(), new CosUploadCallBack() {
            @Override
            public void onSleep(double v) {
                uploadCallBack.onSleep(v);
            }

            @Override
            public void onComplete(String s) {
                uploadCallBack.onComplete(localMedia);
            }

            @Override
            public void onError(String s) {
                uploadCallBack.onError(s);
            }
        });
    }

    /**
     * 上传单个文件到COS
     * @param context 上下文
     * @param fileName 文件名
     * @param filePath 文件本地地址
     * @param uploadCallBack 上传完毕回调
     */
    public static void cosUpload(Context context, String fileName, String filePath, CosUploadCallBack uploadCallBack){
        COS.getInstance().uploadFile(context, FormBuilder.BUCKET_NAME, fileName, filePath, null, uploadCallBack);
    }

    /**
     * 上传多张图片到COS
     * @param context 上下文
     * @param localMedia 图片列表
     * @param uploadCallBack 上传完毕回调
     */
    public static void cosUploadListMedia(Context context, List<MLocalMedia>  localMedia, UploadMediaListener uploadCallBack){
        List<Pair<String,String>> fileNameAndPaths = new ArrayList<>();
        for (MLocalMedia mLocalMedia : localMedia) {
            fileNameAndPaths.add(new Pair<>(mLocalMedia.urlPath,mLocalMedia.getRealPath()));
        }

        Observable.create(new ObservableOnSubscribe<MLocalMedia>() {
            @Override
            public void subscribe(ObservableEmitter<MLocalMedia> e) throws Exception {
                COS.getInstance().uploadMultipleFile(context, FormBuilder.BUCKET_NAME, fileNameAndPaths, new CosUploadMultipleCallBack() {
                    @Override
                    public void onSleep(double v) {
                        uploadCallBack.onSleep(v);
                    }

                    @Override
                    public void onComplete(String s, int i) {
                        uploadCallBack.onComplete(localMedia.get(i));
                    }

                    @Override
                    public void onCompleteAll() {
                        uploadCallBack.onCompleteAll(localMedia);
                    }

                    @Override
                    public void onError(String s) {
                        uploadCallBack.onError(s);
                    }
                });
            }
        }).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())
        .subscribe(new MyObserver<MLocalMedia>() {
            @Override
            public void onNext(MLocalMedia localMedia) {

            }
        });





    }

    /**
     * 上传多个文件到cos
     * @param context 上下文
     * @param fileNameAndPaths 文件 文件名称，文件地址
     * @param uploadCallBack 上传完毕回调
     */
    public static void cosUploadListFile(Context context, List<Pair<String,String>> fileNameAndPaths, CosUploadMultipleCallBack uploadCallBack) {
        COS.getInstance().uploadMultipleFile(context, FormBuilder.BUCKET_NAME, fileNameAndPaths, uploadCallBack);
    }

    /**
     * 删除COS文件
     * @param context 上下文
     * @param fileSrc 文件名称
     * @param cosDeleteCallBack 删除完毕回调
     */
    public static void cosDeleteFile(Context context,String fileSrc,CosDeleteCallBack cosDeleteCallBack){
        COS.getInstance().deleteFile(context, FormBuilder.BUCKET_NAME, fileSrc, cosDeleteCallBack);
    }


    /**
     * 选项改变后判断其所关联的字段，设置显示或隐藏
     * 1、先获取该字段所有选项所关联的字段
     * 2、再获取当前选择的选项所关联的字段
     * 3、两者对比
     * @param allFieldView 所有字段的view ，Map<字段编号，字段view>
     * @param formFieldAllOptionsIdList 字段的所有选项  List<选项编号>
     * @param formOptionAllReFieldMap 字段选项所关联的字段 Map<选项编号，字段编号[]>
     * @param selectOptionIdArray 当前所选择的选项  选项编号[]
     */
    public static void FieldOptionChanged(Map<Long, View> allFieldView,
                                          List<Long> formFieldAllOptionsIdList,
                                          Map<Long,Long[]> formOptionAllReFieldMap,
                                          Long[] selectOptionIdArray) {
        Observable.create(new ObservableOnSubscribe<Pair<View,Boolean>>() {
                    @Override
                    public void subscribe(ObservableEmitter<Pair<View, Boolean>> e)  {
                        //获取该字段所关联的所有字段
                        List<Long> allReFieldId = new ArrayList<>();
                        //需要显示的字段
                        List<Long> showReFieldId = new ArrayList<>();
                        if (formFieldAllOptionsIdList != null && !formFieldAllOptionsIdList.isEmpty()) {
                            //遍历选项 获取选项所关联的字段
                            for (Long optionId : formFieldAllOptionsIdList) {
                                //当前遍历的选项所关联的字段
                                Long[] optionReFieldArray = formOptionAllReFieldMap.get(optionId);
                                //获取字段id 以及将当前选择的选项所关联的字段置为显示
                                if (optionReFieldArray != null) {
                                    List<Long> thisReField = new ArrayList<>(Arrays.asList(optionReFieldArray));
                                    allReFieldId.addAll(thisReField);
                                    //判断当前的选项是否时选择的当前选择的选项关联的字段
                                    for (Long sOptionId : selectOptionIdArray) {
                                        if (Objects.equals(sOptionId, optionId)) {
                                            showReFieldId.addAll(thisReField);
                                            break;
                                        }
                                    }
                                }
                            }

                            //遍历当前字段的选项所关联的所有字段
                            if (!allReFieldId.isEmpty()) {
                                for (Long l : allReFieldId) {
                                    //包含代表要显示
                                    boolean isShow = showReFieldId.contains(l);
                                    View view = allFieldView.get(l);
                                    if (view != null) {
                                        e.onNext(new Pair<>(view,isShow));
                                    }
                                }
                            }
                        }
                        e.onComplete();
                    }
                }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new MyObserver<Pair<View, Boolean>>() {
                    @Override
                    public void onNext(Pair<View, Boolean> pair) {
                        if (pair.second) {
                            if (pair.first.getVisibility() == View.GONE) {
                                pair.first.post(()-> pair.first.setVisibility(View.VISIBLE));
                            }
                        } else {
                            if (pair.first.getVisibility() == View.VISIBLE) {
                                pair.first.post(()-> pair.first.setVisibility(View.GONE));
                            }
                        }
                    }
                });
    }


    public interface OptionChangeModifyFieldViewCallBack{
        void onModify(View view,boolean isShow);
    }



    public interface UploadMediaListener {
        void onSleep(double v);
        void onComplete(MLocalMedia localMedia);
        void onCompleteAll(List<MLocalMedia> localMediaList);
        void onError(String s);
    }

}
